<script setup lang="ts">
import {computed, h, onMounted, ref} from 'vue';
import {Notification} from '@arco-design/web-vue';
import {IconDelete, IconDownload} from '@arco-design/web-vue/es/icon';
import {invoke} from "@tauri-apps/api/core";
import {useRoute} from 'vue-router';
import {Chart, ChartVersion} from '@/model/Chart.ts';
import {CacheApp, LocalStorage} from "@/utils/cache.ts";
import TarotIcon from "@/components/TarotIcon.vue";
import TarotTerminal from "@/components/TarotTerminal.vue";

// 定义应用存储
const currentApp = ref<CacheApp>({} as CacheApp);

// 定义搜索关键字
const searchKeyword = ref('');

// 定义chart搜索加载
const loading = ref(false);

// 定义应用对应的Charts列表
const charts = ref<Array<Chart>>([] as Array<Chart>);

// 定义当前选中的Chart
const currentChart = ref<Chart>({} as Chart);


// 下载相关状态
const downloadProgress = ref(0);
const downloadFileName = ref("");
const downloadStatus = ref("");

const currentChartVersion = ref<ChartVersion>({} as ChartVersion);
const visible = ref<boolean>(false);

/**
 * @function getAppInfo
 * @description 获取应用信息
 * @author xincan
 */
const getAppInfo = async () => {
  const params = useRoute().query
  // 通过点击应用管理跳转过来的, 获取应用id
  if (JSON.stringify(params) !== '{}' && (params.appId !== undefined)) {
    currentApp.value = await invoke("get_app", { id: params.appId });
  }else{
    // 获取缓存数据, 提取其总selected为true的对象
    const store = new LocalStorage('get').store
    if (store.length === 0) {
      Notification.warning("请先选择一个应用")
      return;
    }
    const selectedApps = store.filter((app: any) => app.selected);
    if (selectedApps.length === 0) {
      Notification.warning("请先选择一个应用")
      return;
    }
    currentApp.value = selectedApps[0];
  }
}

/**
 * @function getCharts
 * @description 获取Charts列表
 * @author xincan
 */
const getCharts = async () => {
  charts.value = [];
  currentChart.value = {} as Chart;
  if (Object.keys(currentApp.value).length === 0 || currentApp.value === null) {
    return;
  }
  try {
    const response = await invoke("get_charts", {url: currentApp.value.url + "/api/charts"});
    // 将HashMap转换为数组格式
    const chartMap = response as Record<string, Array<ChartVersion>>;
    charts.value = Object.entries(chartMap).map(([name, versions]) => ({ name, versions }));

    selectChart(charts.value[0] as Chart)
  } catch (error) {
    console.error(error);
    Notification.error('获取Charts列表失败');
  }
};

/**
 * @function formatDate
 * @description 时间戳转换为格式化字符串
 * @author xincan
 * @param       timestamp   时间戳
 * @returns                 格式化后的时间字符串
 */
const formatDate = (timestamp: number): string => {
  const date = new Date(timestamp);
  const dateString = date.toLocaleString('sv-SE'); // 使用瑞典 locale 获取 yyyy-MM-dd HH:mm:ss 格式
  return dateString.replace(/\b\d\b/g, match => `0${match}`); // 对单位数补零
};

/**
 * @function filteredCharts
 * @description 计算属性：过滤后的charts列表
 * @author xincan
 * @param       charts  源数据
 * @returns             过滤后的数据
 */
const filteredCharts = computed(() => {
  if (!searchKeyword.value.trim()) {
    return charts.value;
  }
  const keyword = searchKeyword.value.toLowerCase();
  return  charts.value.filter(chart =>
      chart.name.toLowerCase().includes(keyword)
  );
});

/**
 * @function handleSearch
 * @description 搜索处理方法
 * @author xincan
 * @param value 搜索关键字
 */
const handleSearch = (value: string) => {
  searchKeyword.value = value;
  if (filteredCharts.value.length === 1) {
    const chart = filteredCharts.value[0] as Chart;
    selectChart(chart);
  }
};

/**
 * @function selectChart
 * @description 选择Chart
 * @author xincan
 * @param chart Chart对象
 */
const selectChart = (chart: Chart) => {
  console.log(chart.versions)
  currentChart.value = chart;
};

// 安装版本
// const handleInstall = async (version: any) => {
//   console.log(version);
//   console.log(`${app.value.url}/api/charts/${currentChart.value.name}/${version.version}`);
// };

/**
 * @function handleViewVersion
 * @description 查看版本信息
 * @author xincan
 * @param version 版本对象
 */
const handleViewVersion = (version: ChartVersion) => {
  currentChartVersion.value = version;
  visible.value = true;
}

/**
 * @function handleDeleteVersion
 * @description 删除版本
 * @author xincan
 * @param version 版本对象
 */
const handleDeleteVersion = async (version: ChartVersion) => {
  try {
    const response = await fetch(`${currentApp.value.url}/api/charts/${currentChart.value.name}/${version.version}`, {
      method: 'DELETE'
    });
    if (!response.ok) {
      console.error(response.statusText);
      Notification.error('删除失败');
    }
    currentChart.value.versions = currentChart.value.versions.filter(
        v => v.version !== version.version
    );
    Notification.success('删除成功');
  } catch (error) {
    console.error(error);
    Notification.error('删除失败');
  }
};

/**
 * @function downloadChart
 * @description 下载文件
 * @author xincan
 * @param record 文件对象
 */
async function downloadChart(record: any) {
  try {
    const url = record.urls[0]
    // 重置下载状态
    downloadProgress.value = 0;
    downloadStatus.value = "downloading";
    downloadFileName.value = url.split("/").pop() || "unknown";

    // 创建下载通知
    Notification.info({
      id: 'download-notification',
      title: `下载文件: ${downloadFileName.value}`,
      content: () => h('div', [
        h('div', { class: 'download-progress' }, [
          h('a-progress', {
            percent: downloadProgress.value,
            status: downloadStatus.value === 'error' ? 'error' : downloadStatus.value === 'completed' ? 'success' : 'normal',
            style: 'margin: 10px 0;'
          }),
          h('div', { class: 'download-info' }, [
            downloadStatus.value === 'downloading' ? '正在下载...' :
                downloadStatus.value === 'completed' ? '下载完成' :
                    downloadStatus.value === 'error' ? '下载失败' : ''
          ])
        ])
      ]),
      closable: downloadStatus.value !== 'downloading',
      duration: downloadStatus.value === 'completed' ? 3000 : 0
    });

    const response = await invoke("download_file", { url: currentApp.value.url + "/" + url });
    downloadProgress.value = 100;
    downloadStatus.value = "completed";
    console.log("下载成功:", response);

    // 创建成功完成通知
    Notification.success({
      id: 'download-notification',
      title: `下载文件: ${downloadFileName.value}`,
      content: () => h('div', [
        h('div', { class: 'download-progress' }, [
          h('a-progress', {
            percent: 100,
            status: 'success',
            style: 'margin: 10px 0;'
          }),
          h('div', { class: 'download-info' }, ['下载完成'])
        ])
      ]),
      closable: true,
      duration: 3000
    });
  } catch (error) {
    console.error("下载失败:", error);
    downloadStatus.value = "error";

    // 更新通知为错误状态
    Notification.error({
      id: 'download-notification',
      title: `下载失败: ${downloadFileName.value}`,
      content: '下载过程中发生错误',
      closable: false,
      duration: 3000
    });
  }
}

onMounted(async () => {
  await getAppInfo();
  await getCharts();

});

</script>

<template>
  <div class="container">
    <!-- 左侧列表 -->
    <a-resize-box class="arco-resize-box-left" :directions="['right']" >
      <!-- 左侧列表 -->
      <div class="panel">
        <div class="panel-header">
          <a-input-search v-model="searchKeyword" placeholder="搜索Chart" allow-clear :loading="loading" @search="handleSearch"/>
        </div>
        <div class="panel-content">
          <a-list :bordered="false" :scrollbar="false">
            <a-list-item
                v-for="chart in filteredCharts as Array<Chart>"
                :key="chart.name"
                @click="selectChart(chart as Chart)"
                :class="{ active: currentChart?.name === chart.name }"
            >
              <div class="version-info">
                <span class="version-text">{{ chart.name }}</span>
                <span class="version-badge">{{ chart.versions.length }}</span>
              </div>

            </a-list-item>
          </a-list>
        </div>
      </div>
    </a-resize-box>
    <!-- 右侧内容 -->
<!--    <a-resize-box class="arco-resize-box-bottom" :directions="['bottom']" >-->
      <div class="panel arco-resize-box-bottom">
        <!-- 右侧顶部内容 -->
        <div class="panel-header">
          <span v-if="currentChart" class="text-muted">{{ currentChart.name }}</span>
          <span v-else class="text-muted">请选择一个Chart</span>
        </div>
        <!-- 列表, 终端 -->
        <a-split direction="vertical" default-size="1" min="40px" max="1" class="terminal-split">
          <template #first>
            <!-- 版本查询 -->
            <a-typography-paragraph>
              <div class="version-list">
                <a-table
                :data="currentChart?.versions || []"
                :pagination="false"
                :bordered="false"
                row-key="version"
                :scroll="{ x: 'max-content' }"
                style="width: 100%"
            >
              <template #columns>
                <a-table-column title="版本" data-index="version"  fixed="left"/>
                <a-table-column title="描述" data-index="description" />
                <a-table-column title="摘要" data-index="digest" />
                <a-table-column title="类型" data-index="type" />
                <a-table-column title="创建时间" data-index="created" >
                  <template #cell="{ record }">
                    {{ formatDate(record.created) }}
                  </template>
                </a-table-column>
                <a-table-column title="操作" :width="140" fixed="right" :body-cell-style="{ position: 'sticky', right: 0, zIndex: 1, background: 'var(--theme-bg-light)' }">
                  <template #cell="{ record }">
                    <a-space>
                      <a-tooltip content="下载" mini>
                        <a-button type="primary" shape="circle" size="mini" @click="downloadChart(record)">
                          <icon-download />
                        </a-button>
                      </a-tooltip>
                      <a-tooltip content="详情" mini>
                        <a-button type="primary" shape="circle" size="mini" @click="handleViewVersion(record)">
                          <icon-list />
                        </a-button>
                      </a-tooltip>
                      <a-tooltip content="删除" mini>
                        <a-popconfirm content="确定要删除这个版本吗？" @ok="handleDeleteVersion(record)" position="br">
                          <a-button type="primary" shape="circle" size="mini" status="danger">
                            <icon-delete />
                          </a-button>
                        </a-popconfirm>
                      </a-tooltip>
                    </a-space>
                  </template>
                </a-table-column>
              </template>
            </a-table>
              </div>
          </a-typography-paragraph>
          </template>
          <template #resize-trigger>
            <div class="resize-trigger-terminal" >
              <div class="resize-trigger-terminal-title">
                <tarot-icon name="terminal-2" size="18" />
                <div>终端</div>
              </div>
              <div class="resize-trigger-terminal-btn"></div>
            </div>
          </template>
          <template #second>
            <!-- 终端窗口 -->
            <a-typography-paragraph class="terminal-wrapper">
              <div class="terminal">
                <TarotTerminal />
              </div>
            </a-typography-paragraph>
          </template>
        </a-split>

      </div>
<!--    </a-resize-box>-->
    <a-drawer :width="500" :visible="visible" :hide-cancel="true" ok-text="关闭" @ok="visible = !visible" @cancel="visible = !visible" unmountOnClose >
      <template #title><icon-list />详细信息</template>
      <a-form :model="currentChartVersion" disabled>
        <a-form-item label="名称">
          <a-input v-model="currentChartVersion.name" />
        </a-form-item>
        <a-form-item label="API版本">
          <a-input v-model="currentChartVersion.apiVersion" />
        </a-form-item>
        <a-form-item label="应用版本">
          <a-input v-model="currentChartVersion.appVersion" />
        </a-form-item>
        <a-form-item label="类型">
          <a-input v-model="currentChartVersion.type" />
        </a-form-item>
        <a-form-item label="摘要">
          <a-textarea :rows="14" :cols="80" v-model="currentChartVersion.digest" />
        </a-form-item>
        <a-form-item label="地址" v-for="(url, index) in currentChartVersion.urls" :key="index">
          <a-input :model-value="url" @update:model-value="(val: string) => currentChartVersion.urls[index] = val" />
        </a-form-item>
        <a-form-item label="创建时间">
          <a-input v-model="currentChartVersion.created" />
        </a-form-item>
        <a-form-item label="描述">
          <a-textarea v-model="currentChartVersion.description" />
        </a-form-item>

      </a-form>
    </a-drawer>

  </div>

</template>

<style lang="scss" scoped>
.container {
  display: flex;
  height: 100%;
  box-sizing: border-box;
  .active {
    background-color: var(--theme-10)!important;
    :deep(.arco-list-item-meta-title) {
      color: var(--color-white)!important;
    }
  }
}

.arco-resize-box-left{
  width: 240px;
  min-width: 240px;
  max-width: 440px;
  min-height: 500px;
  max-height: calc(100vh - 48px)!important;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;

  .version-info {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex: 1;
    box-sizing: border-box;
  }

  .version-text {
    flex-shrink: 1;
    color: var(--theme-3);
    font-size: 14px;
    font-weight: bold;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: left;
    padding: 0 8px;
  }

  .version-badge {
    background-color: var(--theme-8);
    color: var(--theme-3);
    padding: 2px 8px;
    border-radius: 100%;
    font-weight: 500;
    flex-shrink: 0;
    white-space: nowrap;
  }

}

.version-list {
  display: flex;
  flex: 1;
  padding: 8px
}

.arco-resize-box-bottom {
  flex: 1;
  width: 500px;
  min-width: 500px;
  max-width: 100%;
  min-height: 300px;
  max-height: calc(100vh - 48px)!important;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;

  .terminal-split {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
    height: 100%;
    width: 100%;
  }

  :deep(.arco-split) {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
    height: 100%;
    width: 100%;

    .arco-split-pane.arco-split-pane-first {
      flex: 0 0 calc(100% - 34px);
    }

    .shrink-start {
      flex: 0 0 calc(0% - 34px)!important;
    }

    .shrink-end {
      flex: 0 0 calc(100% - 300px)!important;
    }

    .arco-split-pane.arco-split-pane-second {
      flex: 1;
      min-height: 0;
      margin-top: -34px;
      padding: 3px 6px;
      box-sizing: border-box;
      display: flex;
      flex-direction: column;
      overflow: hidden;
      position: relative;
    }

    .arco-split-trigger {
      height: 34px;
      position: relative;
      bottom: 19px;
      z-index: 99;
    }
    
    .terminal-wrapper {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      display: flex;
      flex-direction: column;
      margin: 0;
      padding-top: 16px;
      width: 100%;
      height: 100%;
      box-sizing: border-box;
      .terminal {
        display: flex;
        flex: 1;
        flex-direction: column;
        min-height: 0;
        width: 100%;
        height: 100%;
        overflow: hidden;
        box-sizing: border-box;
      }
    }

  }

  .resize-trigger-terminal {
    display: flex;
    align-items: center;
    height: 34px;
    padding: 0 8px;
    box-sizing: border-box;
    background-color: var(--theme-bg-light);
    border: 1px solid var(--theme-bg-content);

    .resize-trigger-terminal-title {
      display: flex;
      flex: 1;
      justify-items: flex-start;
      color: var(--color-text-3);
      align-items: center;
      div {
        font-size: 16px;
        margin-left: 8px;
        vertical-align: text-top;
      }
    }

    .resize-trigger-terminal-btn {
      display: flex;
      align-items: center;
      gap: 8px;
      button {
        background-color: var(--theme-bg-content)!important;
        color: var(--theme-primary);
        font-size: 12px;
        font-weight: bold;
        &:hover {
          background-color: var(--theme-primary)!important;
          color: white;
        }
      }
    }
  }
}

.panel {
  height: 100%;
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  .panel-header {
    padding: 8px;
    display: flex;
    align-items: center;
    gap: 8px;
    border-bottom: 1px solid var(--theme-bg-light)!important;

    .text-muted {
      color: var(--theme-primary)!important;
      padding: 8px;
      border-radius: 4px;
      font-size: 14px;
      font-weight: bold;
    }

    .arco-input-wrapper:hover,
    .arco-input-wrapper:focus-within {
      border-color: var(--theme-primary)!important;
    }

    .arco-input-search {
      width: 100%;
      background-color: var(--theme-bg-light)!important;
      :deep(.arco-icon) {
        color: var(--theme-primary);
      }
      :deep(.arco-icon-hover:hover::before) {
        background-color: var(--theme-bg-light)!important;
      }
      color: var(--color-white)!important;

    }
  }
  .panel-content {
    flex: 1;
    padding: 8px;
    overflow: auto;
    scrollbar-width: none; /* Firefox */
    -ms-overflow-style: none;  /* IE and Edge */
  }
  .panel-content::-webkit-scrollbar {
    display: none; /* Chrome, Safari, Opera */
  }
}

.arco-list-wrapper {
  .arco-list-header, .arco-list-item:not(:last-child) {
    border-bottom: none;
  }
  :deep(.arco-list-content-wrapper) {
    .arco-list-content {
      >.arco-list-item {
        padding: 8px;
        margin: 8px 0;
        background-color: var(--theme-bg-light);
        border-radius: 4px;
        flex: 1;
        .arco-list-item-main {
          width: 100%;
        }
      }
      >.arco-list-item:first-child {
        margin-top: 0;
      }
      >.arco-list-item:last-child {
        margin-bottom: 0;
      }
      >.arco-list-item:hover {
        background-color: var(--theme-10);
        .arco-list-item-meta-title {
          color: var(--color-white)!important;
        }
        cursor: pointer;
      }
    }
  }

}

:deep(.arco-resizebox-trigger-icon-wrapper) {
  background-color: var(--theme-bg)!important;
  color: var(--theme-primary)
}

:deep(.arco-list-item-meta-description) {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: var(--theme-3);
  font-size: 12px;
  margin-top: 4px;
  width: 100%;
}

:deep(.arco-table-td-content) {
  text-align: center;
}

:deep(.arco-scrollbar-track){
  display: none;
}
</style>